interface Rect {
    w: number; //需要图片宽度
    h: number; //需要图片高度
    x: number; //开始操作横坐标
    y: number; //开始操作纵坐标
}

/**
 * @class
 * @description 对图片进行处理，
 */

class ChangeImages {
    /**
     * @function
     * @description 裁剪图片
     * @param {String} imageUrl -  图片地址
     * @param {rect} rect -  图片裁剪位置及宽高
     * @param {String} crossOrigin -  跨域类型
     * @return {Promise} 返回裁剪后图片地址
     * @example
     *   new class().cropImage(imageUrl，rect)
     */

    static cropImage(imageUrl: string, rect: Rect, crossOrigin: string = 'anonymous'): Promise<string> {
        const { x, y, w, h } = rect;
        const image = new Image();
        const canvas = document.createElement('canvas');
        image.crossOrigin = crossOrigin; //设置跨域
        image.src = imageUrl;
        canvas.width = w;
        canvas.height = h;
        const context = canvas.getContext('2d');
        return new Promise((resolve, reject) => {
            image.onload = () => {
                context?.drawImage(image, x, y, w, h, 0, 0, w, h);
                resolve(canvas.toDataURL('image/png'));
            };
            image.onerror = (error) => {
                reject(error);
            };
        });
    }

    /**
     * @function
     * @description 在图片绘制矩形
     * @param {String} imageUrl -  图片地址
     * @param {rect} rects -  图片绘制位置及宽高
     * @param {string} color -  图片绘制的颜色
     * @return {Promise} 返回绘制后图片地址
     * @example
     *   new class().drawBoxOnImage(imageUrl，rects)
     */

    static drawBoxOnImage(imageUrl: string, rects: Rect[] | Rect, color: string = 'red'): Promise<string> {
        const image = new Image();
        const canvas = document.createElement('canvas');
        const ctx = canvas.getContext('2d');
        image.src = imageUrl;
        return new Promise((resolve, reject) => {
            image.onload = () => {
                canvas.width = image.width;
                canvas.height = image.height;
                ctx?.drawImage(image, 0, 0);
                ctx?.beginPath();
                ctx && (ctx.lineWidth = 5);
                ctx && (ctx.strokeStyle = color);
                Array.isArray(rects)
                    ? rects.forEach(({ x, y, w, h }: Rect) => ctx?.rect(x, y, w, h))
                    : ctx?.rect(rects.x, rects.y, rects.w, rects.h);
                ctx?.stroke();
                resolve(canvas.toDataURL('image/png'));
            };
            image.onerror = (error) => {
                reject(error);
            };
        });
    }
    /**
     * @function
     * @description 将 base64 数据图片转换成 http 浏览器直接能打开的地址
     * @param {String} base64Data -  图片数据
     * @return {String} 返回绘制后图片地址
     * @example
     *   class.base64ConversionHttp(base64Data)
     */
    static base64ConversionHttp(base64Data: string): string {
        const [header, body] = base64Data.split(',');
        const mime = header?.match(/:(.*?);/)?.[1] ?? '';
        const byteCharacters = atob(body || base64Data);
        const byteNumbers = new Array(byteCharacters.length);
        for (let i = 0; i < byteCharacters.length; i++) {
            byteNumbers[i] = byteCharacters.charCodeAt(i);
        }
        const byteArray = new Uint8Array(byteNumbers);
        const blob = new Blob([byteArray], { type: mime || 'image/png' });
        return URL.createObjectURL(blob);
    }
    /**
     * @function
     * @description 将 file 图片转成 base64
     * @param {Blob} file -  图片数据
     * @param {Function} collback -  图片数据回调
     * @return {Promise} 返回图片文件
     * @example
     *   class.fileConversionBase64(file,collback)
     */
    static fileConversionBase64(file: Blob, collback: (arg0: string | ArrayBuffer | null) => void): Promise<Blob> {
        return new Promise((resolve, reject) => {
            const reader = new FileReader();
            reader.readAsDataURL(file);
            reader.onload = () => {
                const base64Data = reader.result;
                collback(base64Data);
                resolve(file);
            };
            reader.onerror = (error) => reject(error);
        });
    }
}
export default ChangeImages;
